package pruebasUnitarias;

import civilizacion.Civilizacion;
import edificios.Casa;
import edificios.Edificio;
import excepcionesRegion.eRegionNoExistente;
import excepcionesUnidades.ExcepMovimientoInvalido;
import excepcionesUnidades.ExcepSinMovimiento;
import unidades.Civil;
import unidades.Soldado;
import unidades.Unidad;
import mapas.Mapa;
import mapas.Region;
import junit.framework.TestCase;

public class PruebaMovimientosUnidad extends TestCase {
	//atributos de la prueba
	private Region r1;
	private Region r2;
	private Region r3;
	private Mapa mapa;
	private Unidad unidad;
	private Civilizacion c;
	
	public PruebaMovimientosUnidad(){
		mapa = new Mapa();
		c = new Civilizacion("C",mapa);
	}
	
	public void testMovimientosUnidadNoCivilARegionNoConquistada(){
		r1 = new Region("R1",1);
		r2 = new Region("R2",1);
		r3 = new Region("R2",1);
		mapa.AgregarRegion(r1);
		mapa.AgregarRegion(r2);
		mapa.AgregarRegion(r3);
		try {
			mapa.setLimitrofes(r1,r2);
			mapa.setLimitrofes(r2,r3);
		}
		catch (eRegionNoExistente e) {}
		//Creo una unidad cualquiera distinta de civil
		unidad = new Soldado(c,r1);
		//Conquisto la region r1, agregando una casa y un civil
		Unidad civil = new Civil(c, r1);
		r1.agregar(civil);
		Edificio casa = new Casa(c, r1);
		r1.agregar(casa);
		//La region tendria que estar conquistada
		assertTrue(r1.estaConquistada());
		r1.agregar(unidad);
		try {
				mapa.moverUnidad(unidad,r2);
			} catch (ExcepMovimientoInvalido e) {
				//No se tendria que poder mover entonces tendria que tirar excepcion
				mapa.QuitarRegion(r1);
				mapa.QuitarRegion(r2);
				mapa.QuitarRegion(r3);
				return;
			} catch (ExcepSinMovimiento e) {
				fail("El movimiento deberia ser invalido, sin embargo la unidad tiene desplazamiento restante ");			
			}
		fail("No deberia haber llegado ya que no tiene conquistada esa region");	
	}
	
	public void testMovimientosCivilARegionNoConquistada(){
		r1 = new Region("R1",1);
		r2 = new Region("R2",1);
		r3 = new Region("R3",1);
		mapa.AgregarRegion(r1);
		mapa.AgregarRegion(r2);
		mapa.AgregarRegion(r3);
		try {
			mapa.setLimitrofes(r1,r2);
			mapa.setLimitrofes(r2,r3);
		}
		catch (eRegionNoExistente e) {}
		unidad = new Civil(c,r1);
		//Conquisto la region r1, agregando una casa y un civil
		Unidad civil = new Civil(c, r1);
		r1.agregar(civil);
		Edificio casa = new Casa(c, r1);
		r1.agregar(casa);
		//La region tendria que estar conquistada
		assertTrue(r1.estaConquistada());
		r1.agregar(unidad);
		try {
				mapa.moverUnidad(unidad,r2);
		} catch (ExcepMovimientoInvalido e1) {
			fail("El civil tendria que poder moverse a una region limitrofe no conquistada ");
		} catch (ExcepSinMovimiento e1) {
			fail("El civil tiene movimiento suficiente");
		}
		//Creo otro civil
		unidad = new Civil(c,r1);
		
			try {
				mapa.moverUnidad(unidad,r2);
				//Le doy movimiento para volver a moverse
				unidad.setDespRestante(1);
				mapa.moverUnidad(unidad, r3);
			} catch (ExcepMovimientoInvalido e) {
				mapa.QuitarRegion(r1);
				mapa.QuitarRegion(r2);
				mapa.QuitarRegion(r3);
				return;
			} catch (ExcepSinMovimiento e) {
				fail("El civil tiene desplazamiento suficiente");
			}
		fail("El civil no puede moverse desde una no conquistada a otra no conquistada");
	}
	public void testMovimientosCivilARegionNoConquistadaConElementosDeOtro(){
		r1 = new Region("R1",1);
		r2 = new Region("R2",1);
		r3 = new Region("R2",1);
		mapa.AgregarRegion(r1);
		mapa.AgregarRegion(r2);
		mapa.AgregarRegion(r3);
		try {
			mapa.setLimitrofes(r1,r2);
			mapa.setLimitrofes(r2,r3);
		}
		catch (eRegionNoExistente e) {}
		unidad = new Civil(c,r1);
		//Conquisto la region r1, agregando una casa y un civil
		Unidad civil = new Civil(c, r1);
		r1.agregar(civil);
		Edificio casa = new Casa(c, r1);
		r1.agregar(casa);
		//La region tendria que estar conquistada
		assertTrue(r1.estaConquistada());
		r1.agregar(unidad);
		//Agrego un civil de otra civilizacion en la region destino
		Civilizacion c2 = new Civilizacion("C2",mapa);
		Unidad civil2 = new Civil(c2, r1);
		r2.agregar(civil2);
		try {
			mapa.moverUnidad(unidad,r2);
		}
		catch (ExcepMovimientoInvalido e) {
			mapa.QuitarRegion(r1);
			mapa.QuitarRegion(r2);
			mapa.QuitarRegion(r3);
			return;
		} catch (ExcepSinMovimiento e) {
			fail("El civil tiene desplazamiento suficiente");
		}
			fail("El civil no puede moverse a una no conquistada con un elemento de otra civilizacion");
	}
	public void testMovimientosUnidadARegionNoLimitrofe(){
		r1 = new Region("R1",1);
		r2 = new Region("R2",1);
		r3 = new Region("R2",1);
		mapa.AgregarRegion(r1);
		mapa.AgregarRegion(r2);
		mapa.AgregarRegion(r3);
		unidad = new Civil(c,r1);
		//Conquisto la region r1, agregando una casa y un civil
		Unidad civil = new Civil(c, r1);
		r1.agregar(civil);
		Edificio casa = new Casa(c, r1);
		r1.agregar(casa);
		//La region tendria que estar conquistada
		assertTrue(r1.estaConquistada());
		r1.agregar(unidad);
		//Conquisto la region r2, agregando una casa y un civil
		Unidad civil2 = new Civil(c, r1);
		r2.agregar(civil2);
		Edificio casa2 = new Casa(c, r1);
		r2.agregar(casa2);
		//La region tendria que estar conquistada
		assertTrue(r2.estaConquistada());
		try {
			mapa.moverUnidad(unidad,r2);
		}
		catch (ExcepMovimientoInvalido e) {
			mapa.QuitarRegion(r1);
			mapa.QuitarRegion(r2);
			mapa.QuitarRegion(r3);
			return;
		} catch (ExcepSinMovimiento e) {
			fail("El civil tiene desplazamiento suficiente");
		}
		fail("El civil no puede moverse a una region no limitrofe");
	}
	public void testMovimientosUnidadSinMovimiento(){
		r1 = new Region("R1",1);
		r2 = new Region("R2",1);
		r3 = new Region("R2",1);
		mapa.AgregarRegion(r1);
		mapa.AgregarRegion(r2);
		mapa.AgregarRegion(r3);
		try {
			mapa.setLimitrofes(r1,r2);
			mapa.setLimitrofes(r2,r3);
		}
		catch (eRegionNoExistente e) {}
		unidad = new Civil(c,r1);
		//Conquisto la region r1, agregando una casa y un civil
		Unidad civil = new Civil(c, r1);
		r1.agregar(civil);
		Edificio casa = new Casa(c, r1);
		r1.agregar(casa);
		//La region tendria que estar conquistada
		assertTrue(r1.estaConquistada());
		r1.agregar(unidad);
		//Conquisto la region r2, agregando una casa y un civil
		Unidad civil2 = new Civil(c, r2);
		r2.agregar(civil2);
		Edificio casa2 = new Casa(c, r2);
		r2.agregar(casa2);
		//La region tendria que estar conquistada
		assertTrue(r2.estaConquistada());
		//Conquisto la region r3, agregando una casa y un civil
		Unidad civil3 = new Civil(c, r3);
		r3.agregar(civil3);
		Edificio casa3 = new Casa(c, r3);
		r3.agregar(casa3);
		//La region tendria que estar conquistada
		assertTrue(r3.estaConquistada());
		try {
			mapa.moverUnidad(unidad,r2);
			mapa.moverUnidad(unidad,r3);
		}
		catch (ExcepMovimientoInvalido e) {
			fail("El civil tendria que poder hacer el movimiento, si tuviera desp restante");
		} catch (ExcepSinMovimiento e) {
			mapa.QuitarRegion(r1);
			mapa.QuitarRegion(r2);
			mapa.QuitarRegion(r3);
			return;
		}
		fail("El civil no puede moverse 2 veces seguidas, se queda sin movimiento");
	}
}
